﻿/************************************************************************************
 * 工    具：  HK_TaskSystem
 * 
 * 描    述：  HK_TaskSystem 是一套任务管理系统，适用于 `线性及非线性任务流程` 的使用场景，支持任务链的初始化、执行、中断和查询等操作，主要功能如下：
 * 
 *            1.在本项目的 Architecture 中注册 IHK_TaskSystem;
 *            2.本系统分三个层级：任务链 TaskList、任务 Task、条件 Condition
 *            3.对外方法有四个: 
 *              StartNewTaskList(string taskDataName)  //开启 新的 任务链
 *              BreakOffTaskList() // 中断 当前 任务链
 *              AchieveCondition(HK_ConditionType condition) // 达成指定条件
 *              StopTaskAudio() // 停止当前播放的任务语音
 *              ImmediateFinishTaskList() // 立即完成当前任务连（主要用于开发测试） 
 *            4.更推荐使用Command指令来使用TaskSystem，四个对外方法分别对应四个Command：
 *              CMD_StartNewTaskList ：开启新的任务链指令
 *              CMD_BreakOffTaskList ：中断当前任务链指令
 *              CMD_AchieveCondition ：达成指定条件指令
 *              CMD_StopTaskAudio ：停止当前播放的任务语音指令
 *              CMD_ImmediateFinishTaskList ：立即完成当前任务连（主要用于开发测试） 
 *            5.可通过Query来查询某条件是否达成：
 *              Query_ConditionState : 查询某条件是否达成
 *            6.外部可监听事件有六个: 
 *              Event_TaskListStart     // 任务链开始 事件
 *              Event_TaskListFinish    // 任务链结束 事件
 *              Event_TaskListBreadOff  // 任务链中断 事件
 *              Event_TaskStart         // 任务开始 事件
 *              Event_TaskFinish        // 任务结束 事件
 *              Event_ConditionAchieve  // 条件达成 事件
 *                   
 * 版    本：  V1.0
 * 作    者：  京产肠饭
 * 
 * 创    建：  2023/03/13  V1.0
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using UnityEngine;
using QFramework;

namespace HKTools
{
    public interface IHK_TaskSystem : ISystem
    {
        /// <summary>
        /// 开启 新的 任务链
        /// </summary>
        void StartNewTaskList(string taskDataName);

        /// <summary>
        /// 中断 当前 任务链
        /// </summary>
        void BreakOffTaskList();

        /// <summary>
        /// 达成指定条件
        /// </summary>
        void AchieveCondition(HK_ConditionType condition);

        /// <summary>
        /// 停止任务语音
        /// </summary>
        void StopTaskAudio();

        /// <summary>
        /// 立即完成 任务链
        /// </summary>
        void ImmediateFinishTaskList();
    }

    public class HK_TaskSystem : AbstractSystem, IHK_TaskSystem
    {
        IHK_TaskModel taskModel;

        bool isChangeTask = false;

        protected override void OnInit()
        {
            taskModel = this.GetModel<IHK_TaskModel>();

            taskModel.CurTaskList = null;

            this.RegisterEvent<Event_TaskListStart>(e =>
            {
                Debug.LogFormat("<color=#4876FF>----------开始任务链：{0}-----------</color>", e._taskListName);
            });

            this.RegisterEvent<Event_TaskListFinish>(e =>
            {
                Debug.LogFormat("<color=#4876FF>----------结束任务链：{0}-----------</color>", e._taskListName);
            });

            this.RegisterEvent<Event_TaskListBreadOff>(e =>
            {
                Debug.LogFormat("<color=#FF00FF>----------中断任务链：{0}-----------</color>", e._taskListName);
            });

            this.RegisterEvent<Event_TaskStart>(e =>
            {
                Debug.LogFormat("<color=green>Task Start：{0}</color> ", e._taskType);
            });

            this.RegisterEvent<Event_TaskFinish>(e =>
            {
                Debug.LogFormat("<color=green>Task Finish：{0}</color> ", e._taskType);
            });

            this.RegisterEvent<Event_ConditionAchieve>(e =>
            {
                Debug.LogFormat("<color=yellow>Condition：{0} 达成!</color>", e._condition);
            });
        }

        /// <summary>
        /// 开启 新的 任务链
        /// </summary>
        public void StartNewTaskList(string taskListName)
        {
            if (taskModel.CurTaskList != null)
            {
                Debug.LogWarningFormat("当前存在未完成的任务链：{0}，请先完成或中断当前任务链！", taskListName);
                return;
            }

            taskModel.CurTaskListName = taskListName;

            taskModel.CurTaskList = Resources.Load<HK_TaskList>(taskListName);

            if (taskModel.CurTaskList == null)
            {
                Debug.LogErrorFormat("没有读取到任务链：{0}", taskListName);
                return;
            }

            // 发送 任务链开始 事件
            this.SendEvent(new Event_TaskListStart() { _taskListName = taskListName });

            StartOneTask(taskModel.TaskIndex);
        }

        /// <summary>
        /// 中断 当前 任务链
        /// </summary>
        public void BreakOffTaskList()
        {
            if (taskModel.CurTaskList == null)
            {
                Debug.LogWarningFormat("当前没有要中断的任务链！");
                return;
            }

            // 发送 任务链完成 事件
            this.SendEvent(new Event_TaskListBreadOff() { _taskListName = taskModel.CurTaskListName });

            isChangeTask = false;
            taskModel.CurTaskList = null;
            taskModel.CurTaskListName = "";
        }

        /// <summary>
        /// 达成指定条件
        /// </summary>
        public void AchieveCondition(HK_ConditionType condition)
        {
            if (isChangeTask)
                return;

            if (taskModel.CurTaskList == null)
                return;

            // 如果 该条件 已经完成过，则返回
            if (taskModel.AchieveConditions.Contains(condition))
                return;

            for (int i = 0; i < taskModel.CurTask.conditions.Count; i++)
            {
                if (taskModel.CurTask.conditions[i].condition == condition)
                {
                    taskModel.CurTask.conditions[i].isFinish = true;

                    // 发送 某条件达成 事件
                    this.SendEvent(new Event_ConditionAchieve() { _condition = condition });

                    taskModel.AchieveConditions.Add(condition);
                }
            }

            JudgeCurTaskState();
        }

        /// <summary>
        /// 停止任务语音
        /// </summary>
        public void StopTaskAudio()
        {
            AudioKit.StopVoice();
        }

        /// <summary>
        /// 立即结束 任务链
        /// </summary>
        public void ImmediateFinishTaskList()
        {
            isChangeTask = false;
            TaskListFinish();
        }

        // 判断当前任务是否完成
        void JudgeCurTaskState()
        {
            bool isAllFinished = true;

            for (int i = 0; i < taskModel.CurTask.conditions.Count; i++)
            {
                if (!taskModel.CurTask.conditions[i].isFinish)
                    isAllFinished = false;
            }

            if (isAllFinished)
            {
                isChangeTask = true;

                // 发送 某任务完成 事件
                this.SendEvent(new Event_TaskFinish() { _taskType = taskModel.CurTask.task });

                taskModel.CurTask.isFinished = true;

                if (!taskModel.FinishedTasks.Contains(taskModel.CurTask))
                    taskModel.FinishedTasks.Add(taskModel.CurTask);

                taskModel.TaskIndex++;

                if (taskModel.TaskIndex >= taskModel.CurTaskList.list.Count)
                {
                    isChangeTask = false;
                    TaskListFinish();
                    return;
                }

                if (taskModel.CurTask.nextTast != HK_TaskType.None)
                {
                    for (int i = 0; i < taskModel.CurTaskList.list.Count; i++)
                    {
                        if (taskModel.CurTaskList.list[i].task == taskModel.CurTask.nextTast)
                        {
                            taskModel.TaskIndex = i;
                        }
                    }
                }

                if (taskModel.CurTask.nextTaskDelay == 0)
                {
                    StartOneTask(taskModel.TaskIndex);
                    isChangeTask = false;
                }
                else
                {
                    ActionKit.Delay(taskModel.CurTask.nextTaskDelay, () =>
                    {
                        StartOneTask(taskModel.TaskIndex);
                        isChangeTask = false;
                    }).StartGlobal();
                }
            }
        }

        // 开启一个任务
        void StartOneTask(int index)
        {
            if (taskModel.FinishedTasks.Contains(taskModel.CurTaskList.list[index]))
            {
                return;
            }

            taskModel.CurTask = taskModel.CurTaskList.list[index];

            // 发送 某任务开始 事件
            this.SendEvent(new Event_TaskStart() { _taskType = taskModel.CurTask.task });

            taskModel.CurTask.isOn = true;

            if (taskModel.CurTask.taskStartAudio != null)
            {
                ActionKit.Delay(taskModel.CurTask.audioDelay, () =>
                {
                    AudioKit.PlayVoice(taskModel.CurTask.taskStartAudio);
                }).StartGlobal();
            }
        }

        // 任务链完成
        void TaskListFinish()
        {
            // 发送 任务链完成 事件
            this.SendEvent(new Event_TaskListFinish() { _taskListName = taskModel.CurTaskListName });

            taskModel.CurTaskList = null;
            taskModel.CurTaskListName = "";
        }
    }
}